<template>
  <Teleport to="body">
    <Transition
      name="toast"
      enter-active-class="toast-enter-active"
      leave-active-class="toast-leave-active"
      enter-from-class="toast-enter-from"
      leave-to-class="toast-leave-to"
    >
      <div
        v-if="visible"
        class="toast-notification"
        :class="[
          `toast-notification--${type}`,
          {
            'toast-notification--mobile': isMobile,
            'toast-notification--persistent': persistent
          }
        ]"
        @click="handleClick"
      >
        <div class="toast-notification__content">
          <div class="toast-notification__icon">
            <i :class="iconClass" />
          </div>
          <div class="toast-notification__message">
            <div class="toast-notification__title" v-if="title">
              {{ title }}
            </div>
            <div class="toast-notification__text">
              {{ message }}
            </div>
          </div>
          <div class="toast-notification__actions" v-if="showActions">
            <button
              v-if="retryable"
              class="toast-notification__action toast-notification__action--retry"
              @click.stop="handleRetry"
              :disabled="retrying"
            >
              <i v-if="retrying" class="el-icon-loading" />
              <i v-else class="el-icon-refresh" />
              {{ retrying ? '重试中...' : '重试' }}
            </button>
            <button
              class="toast-notification__action toast-notification__action--dismiss"
              @click.stop="handleDismiss"
            >
              <i class="el-icon-close" />
            </button>
          </div>
        </div>
        <div
          v-if="!persistent && duration > 0"
          class="toast-notification__progress"
          :style="{ animationDuration: `${duration}ms` }"
        />
      </div>
    </Transition>
  </Teleport>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useResponsive } from '@/composables/useResponsive'

// Props
interface Props {
  type?: 'success' | 'error' | 'warning' | 'info'
  title?: string
  message: string
  duration?: number
  persistent?: boolean
  retryable?: boolean
  showActions?: boolean
  onRetry?: () => Promise<void> | void
  onDismiss?: () => void
}

const props = withDefaults(defineProps<Props>(), {
  type: 'info',
  duration: 4000,
  persistent: false,
  retryable: false,
  showActions: true
})

// Emits
interface Emits {
  (e: 'close'): void
  (e: 'retry'): void
  (e: 'dismiss'): void
}

const emit = defineEmits<Emits>()

// Composables
const { isMobile } = useResponsive()

// State
const visible = ref(false)
const retrying = ref(false)
let autoCloseTimer: NodeJS.Timeout | null = null

// Computed
const iconClass = computed(() => {
  const iconMap = {
    success: 'el-icon-success',
    error: 'el-icon-error',
    warning: 'el-icon-warning',
    info: 'el-icon-info'
  }
  return iconMap[props.type]
})

// Methods
const show = () => {
  visible.value = true
  
  if (!props.persistent && props.duration > 0) {
    startAutoClose()
  }
}

const hide = () => {
  visible.value = false
  clearAutoClose()
  emit('close')
}

const startAutoClose = () => {
  clearAutoClose()
  autoCloseTimer = setTimeout(() => {
    hide()
  }, props.duration)
}

const clearAutoClose = () => {
  if (autoCloseTimer) {
    clearTimeout(autoCloseTimer)
    autoCloseTimer = null
  }
}

const handleClick = () => {
  if (!props.persistent && !props.showActions) {
    hide()
  }
}

const handleRetry = async () => {
  if (!props.onRetry || retrying.value) return
  
  try {
    retrying.value = true
    await props.onRetry()
    emit('retry')
    hide()
  } catch (error) {
    console.error('Retry failed:', error)
  } finally {
    retrying.value = false
  }
}

const handleDismiss = () => {
  props.onDismiss?.()
  emit('dismiss')
  hide()
}

// Lifecycle
onMounted(() => {
  show()
})

onUnmounted(() => {
  clearAutoClose()
})

// Expose methods
defineExpose({
  show,
  hide
})
</script>

<style lang="scss" scoped>
.toast-notification {
  position: fixed;
  top: 20px;
  right: 20px;
  min-width: 300px;
  max-width: 500px;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 9999;
  overflow: hidden;
  
  &--mobile {
    left: 16px;
    right: 16px;
    top: 16px;
    min-width: auto;
    max-width: none;
  }
  
  &--persistent {
    .toast-notification__progress {
      display: none;
    }
  }
  
  &--success {
    border-left: 4px solid #67c23a;
    
    .toast-notification__icon {
      color: #67c23a;
    }
  }
  
  &--error {
    border-left: 4px solid #f56c6c;
    
    .toast-notification__icon {
      color: #f56c6c;
    }
  }
  
  &--warning {
    border-left: 4px solid #e6a23c;
    
    .toast-notification__icon {
      color: #e6a23c;
    }
  }
  
  &--info {
    border-left: 4px solid #409eff;
    
    .toast-notification__icon {
      color: #409eff;
    }
  }
}

.toast-notification__content {
  display: flex;
  align-items: flex-start;
  padding: 16px;
  gap: 12px;
}

.toast-notification__icon {
  flex-shrink: 0;
  font-size: 20px;
  margin-top: 2px;
}

.toast-notification__message {
  flex: 1;
  min-width: 0;
}

.toast-notification__title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 4px;
  line-height: 1.4;
}

.toast-notification__text {
  font-size: 13px;
  color: #606266;
  line-height: 1.4;
  word-break: break-word;
}

.toast-notification__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.toast-notification__action {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border: none;
  border-radius: 4px;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s;
  
  &--retry {
    background: #409eff;
    color: #fff;
    
    &:hover:not(:disabled) {
      background: #337ecc;
    }
    
    &:disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }
    
    .el-icon-loading {
      animation: spin 1s linear infinite;
    }
  }
  
  &--dismiss {
    background: #f5f7fa;
    color: #909399;
    
    &:hover {
      background: #e4e7ed;
      color: #606266;
    }
  }
}

.toast-notification__progress {
  height: 3px;
  background: linear-gradient(90deg, #409eff, #67c23a);
  animation: progress linear;
  transform-origin: left;
}

@keyframes progress {
  from {
    transform: scaleX(1);
  }
  to {
    transform: scaleX(0);
  }
}

// Toast transitions
.toast-enter-active,
.toast-leave-active {
  transition: all 0.3s ease;
}

.toast-enter-from {
  transform: translateX(100%);
  opacity: 0;
}

.toast-leave-to {
  transform: translateX(100%);
  opacity: 0;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

// Mobile optimizations
@media (max-width: 768px) {
  .toast-notification {
    &:not(.toast-notification--mobile) {
      left: 16px;
      right: 16px;
      min-width: auto;
      max-width: none;
    }
  }
  
  .toast-notification__content {
    padding: 12px;
    gap: 10px;
  }
  
  .toast-notification__icon {
    font-size: 18px;
  }
  
  .toast-notification__title {
    font-size: 13px;
  }
  
  .toast-notification__text {
    font-size: 12px;
  }
  
  .toast-notification__action {
    padding: 6px 10px;
    font-size: 11px;
    min-height: 32px;
  }
}
</style>